home *** CD-ROM | disk | FTP | other *** search
Wrap
Oberon Text | 1993-10-25 | 18.5 KB | 473 lines | [ .Ob./.Ob5]
Syntax10.Scn.Fnt ParcElems Alloc Syntax10i.Scn.Fnt Chicago10.Scn.Fnt MODULE SampleApp; (* mf/od/mf 25.10.93*) (* This Sample Text Editor shows how to use MacOberon to develop standalone Macintosh Applications. This application does NOT show how to write Macintosh programs! It is intended to demonstrate the use of MacOberon, for programmers already familiar with the Macintosh toolbox. Click the following commands to compile, link and launch the application: Compile the toolbox files if necessary: Compiler.Compile MacMemory.Mod/s MacImaging.Mod/s MacToolbox.Mod/s MacFiles.Mod/s MacProcesses.Mod/s MacOSUtils.Mod/s MacMoreToolbox.Mod/s MacText.Mod/s MacIAC.Mod/s ~ Compiler.Compile SampleApp.Mod ~ ApplLinker.Link SampleApp SAMP ~ 2nd parameter is creator ApplLinker.Launch SampleApp Edit.Open DK.MacOberonApp.Text for more information on how to create standalone Macintosh applications using MacOberon. *) IMPORT SYSTEM, TB:=MacToolbox, ME:=MacMemory, TE:=MacText, IM:=MacImaging, MF:=MacFiles, MP:=MacProcesses, MT:=MacMoreToolbox, MO:=MacOSUtils; CONST (* Apple Menu *) mApple=256; iAbout=1; (* File Menu *) mFile=257; iNew=1; iOpen=2; iClose=3; iSave=5; iPageSetUp=7; iPrint=8; iQuit=10; (* Edit Menu *) mEdit=258; iCut=3; iCopy=4; iPaste=5; iClear=6; iSelectAll=8; (* Font Menus *) mFont=259; mSize=260; (* Alerts *) aAbout=1000; (* Controls *) rVScroll=128; DocPtr = POINTER- TO DocRec; DocRec = RECORD (* Datatype for our documents *) data: TE.TEHandle; vScrollBar: TB.ControlHandle; END; wcount: SHORTINT; (* Application Window Number *) gPrint: IM.THPrint; (* global Printhandle *) (* Two general routines for adjusting rectangles of the textwindows *) PROCEDURE GetTERect(window: TB.WindowPtr; VAR teRect: IM.Rect); BEGIN teRect:=window.portRect; IM.InsetRect(teRect, 4, 4 ); DEC(teRect.right, 15); DEC(teRect.bottom, 15) END GetTERect; PROCEDURE AdjustViewRect(docTE: TE.TEHandle); BEGIN docTE.p.viewRect.bottom:= (((docTE.p.viewRect.bottom-docTE.p.viewRect.top) DIV docTE.p.lineHeight)*docTE.p.lineHeight)+docTE.p.viewRect.top END AdjustViewRect; (* Creates and returns a new TextEdit window *) PROCEDURE NewWindow(): TB.WindowPtr; VAR winTitle: ME.Str255; wbounds, tbounds: IM.Rect; window: TB.WindowPtr; text: TE.TEHandle; newDoc: DocPtr; info: TE.FontInfo; BEGIN wbounds.top:=IM.QuickDraw.screenBits.bounds.top+40+10*(wcount MOD 10); (* Open new window *) wbounds.left:=IM.QuickDraw.screenBits.bounds.left+20+10*(wcount MOD 10); wbounds.bottom:=IM.QuickDraw.screenBits.bounds.bottom-20; wbounds.right:=IM.QuickDraw.screenBits.bounds.right-50; INC(wcount); winTitle[0]:=3X; winTitle[1]:=23X; winTitle[2]:=CHR((wcount DIV 10) MOD 10+30H); winTitle[3]:=CHR(wcount MOD 10+30H); window:=TB.NewWindow(NIL, wbounds, winTitle, FALSE, 0, SYSTEM.VAL(TB.WindowPtr, -1), TRUE, 0); IM.SetPort(window); GetTERect(window, tbounds); text:=TE.TENew(tbounds, tbounds); (* Add textedit structure and set default font *) text.p.txFont:=4;text.p.txSize:=9; TE.TextFont(4);TE.TextSize(9); TE.GetFontInfo(info); text.p.lineHeight:=info.ascent+info.descent+info.leading; text.p.fontAscent:=info.ascent; AdjustViewRect(text); TE.TEAutoView(TRUE, text); SYSTEM.PUTREG(0, LONG(LONG(SIZE(DocRec)))); (* use two LONG to prevent from a MOVE.B instruction *) ME.NewPtrClear; SYSTEM.GETREG(8, newDoc); newDoc.data:=text; newDoc.vScrollBar:=TB.GetNewControl(rVScroll, window); (* Add scrollbar *) window.refCon:=SYSTEM.VAL(LONGINT, newDoc); (* We use the window refcon to store our data pointer *) RETURN window END NewWindow; (* Routines for text scrolling and updating *) PROCEDURE AdjustTE(window: TB.WindowPtr); VAR myDoc: DocPtr; BEGIN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); TE.TEPinScroll((myDoc.data.p.viewRect.left-myDoc.data.p.destRect.left), (myDoc.data.p.viewRect.top-myDoc.data.p.destRect.top)-(TB.GetCtlValue(myDoc.vScrollBar)*myDoc.data.p.lineHeight), myDoc.data) END AdjustTE; PROCEDURE AdjustScrollSizes(window: TB.WindowPtr); VAR myDoc: DocPtr; teTop, teRight, teBottom: INTEGER; teRect: IM.Rect; BEGIN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); GetTERect(window, teRect); teTop:=window.portRect.top; teRight:=window.portRect.right; teBottom:=window.portRect.bottom; myDoc.data.p.viewRect:=teRect; AdjustViewRect(myDoc.data); TB.MoveControl(myDoc.vScrollBar, teRight-15, -1); TB.SizeControl(myDoc.vScrollBar, 16, (teBottom-teTop)-13); END AdjustScrollSizes; PROCEDURE AdjustScrollValues(window: TB.WindowPtr); VAR myDoc: DocPtr; max, lines, value: INTEGER; BEGIN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); lines:=myDoc.data.p.nLines; max:=lines-((myDoc.data.p.viewRect.bottom-myDoc.data.p.viewRect.top) DIV myDoc.data.p.lineHeight); IF max<0 THEN max:=0 END; TB.SetCtlMax(myDoc.vScrollBar, max); value:=(myDoc.data.p.viewRect.top-myDoc.data.p.destRect.top) DIV myDoc.data.p.lineHeight; IF value<0 THEN value:=0 END;IF value>max THEN value:=max END; TB.SetCtlValue(myDoc.vScrollBar, value); TB.ShowControl(myDoc.vScrollBar) END AdjustScrollValues; PROCEDURE AdjustScrollBars(window: TB.WindowPtr; resize: BOOLEAN); VAR myDoc: DocPtr; BEGIN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); myDoc.vScrollBar.p.contrlVis:=0; IF resize THEN AdjustScrollSizes(window) END; AdjustScrollValues(window) END AdjustScrollBars; (* Use StandardGetFile to select and open a plain ASCII text file *) PROCEDURE OpenFile; VAR myTypes: MF.SFTypeList; myReply: MF.StandardFileReply; window: TB.WindowPtr; inFile: INTEGER; err: INTEGER; theSize: LONGINT; buffer: ME.Ptr; myDoc: DocPtr; BEGIN myTypes[0]:=054455854H; (* TEXT *) MF.StandardGetFile(NIL, 1, myTypes, myReply); IF myReply.sfGood THEN window:=NewWindow(); myDoc:=SYSTEM.VAL(DocPtr, window.refCon); TB.SetWTitle(window, SYSTEM.VAL(ME.Str255, myReply.sfFile.name)); err:=MF.FSpOpenDF(myReply.sfFile, 0, inFile); err:=MF.GetEOF(inFile, theSize); IF theSize>7FFFH THEN theSize:=7FFFH END; (* Limitation of TextEdit, max 32768 chars *) err:=MF.SetFPos(inFile, 1, 0); SYSTEM.PUTREG(0, 8000H); ME.NewPtr; SYSTEM.GETREG(8, buffer); err:=MF.FSRead(inFile, theSize, buffer); err:=MF.FSClose(inFile); TE.TESetText(buffer, theSize, myDoc.data); AdjustScrollBars(window, TRUE); AdjustTE(window); TB.ShowWindow(window); SYSTEM.PUTREG(8, buffer); ME.DisposePtr END END OpenFile; (* Close the front window *) PROCEDURE CloseWindow; VAR window: TB.WindowPtr; myDoc: DocPtr; BEGIN window:=TB.FrontWindow(); IF window=NIL THEN RETURN END; myDoc:=SYSTEM.VAL(DocPtr, window.refCon); TE.TEDispose(myDoc.data); TB.CloseWindow(window); SYSTEM.PUTREG(8, myDoc); ME.DisposePtr END CloseWindow; (* Save the content of the front window to a file *) PROCEDURE SaveWindow; VAR myReply: MF.StandardFileReply; prompt, defname: ME.Str255; myDoc: DocPtr; window: TB.WindowPtr; myFile: INTEGER; err: INTEGER; size: LONGINT; BEGIN window:=TB.FrontWindow(); IF window=NIL THEN RETURN END; TB.SetStr255(prompt, 'Save file as:'); TB.SetStr255(defname, 'Untitled'); MF.StandardPutFile(prompt, defname, myReply); (* Select a filename *) IF myReply.sfGood THEN IF myReply.sfReplacing THEN err:=MF.FSpDelete(myReply.sfFile) END; myDoc:=SYSTEM.VAL(DocPtr, window.refCon); err:=MF.FSpCreate(myReply.sfFile, 045444954H, 054455854H, 0); (* Create a new file *) err:=MF.FSpOpenDF(myReply.sfFile, 0, myFile); IF err=0 THEN size:=myDoc.data.p.teLength; err:=MF.FSWrite(myFile, size, myDoc.data.p.hText.p); (* Write the text data *) err:=MF.FSClose(myFile) END END END SaveWindow; (* Print the content of the front window *) PROCEDURE DoPageSetUp; VAR ignore: BOOLEAN; BEGIN IM.PrOpen; ignore:=IM.PrStlDialog(gPrint); (* Get Pagesetup *) IM.PrClose END DoPageSetUp; PROCEDURE DoPrint; VAR myDoc: DocPtr; window: TB.WindowPtr; pages: INTEGER; lines: INTEGER; prPort: IM.GrafPtr; line, page: INTEGER; lh, y: INTEGER; BEGIN window:=TB.FrontWindow(); IF window=NIL THEN RETURN END; myDoc:=SYSTEM.VAL(DocPtr, window.refCon); IM.PrOpen; IF IM.PrJobDialog(gPrint) THEN (* Get printing options *) prPort:=IM.PrOpenDoc(gPrint, NIL, 0); lines:= (prPort.portRect.bottom - prPort.portRect.top) DIV myDoc.data.p.lineHeight; pages:= myDoc.data.p.nLines DIV lines; line:=0;page:=0; WHILE page<=pages DO IM.PrOpenPage(prPort, NIL); TE.TextFont(myDoc.data.p.txFont); TE.TextSize(myDoc.data.p.txSize); lh:=myDoc.data.p.lineHeight; y:=lh; REPEAT IM.MoveTo(20, y); TE.DrawText(myDoc.data.p.hText.p, myDoc.data.p.lineStarts[line], myDoc.data.p.lineStarts[line+1]- myDoc.data.p.lineStarts[line]-1); INC(line); INC(y, lh); UNTIL ((line>myDoc.data.p.nLines)OR((line MOD lines)=0)); IM.PrClosePage(prPort); INC(page); END; IM.PrCloseDoc(prPort); END; IM.PrClose END DoPrint; (* Clickroutine for scrollbar *) PROCEDURE VertAction(control: TB.ControlHandle; part: INTEGER); VAR scrollDistance:INTEGER; window: TB.WindowPtr; myDoc: DocPtr; oldSetting, max: INTEGER; BEGIN IF part#0 THEN window:=control.p.contrlOwner; myDoc:=SYSTEM.VAL(DocPtr, window.refCon); CASE part OF | TB.inUpButton, TB.inDownButton: scrollDistance:=1 | TB.inPageUp, TB.inPageDown: scrollDistance:=10 END; IF (part=TB.inDownButton) OR (part=TB.inPageDown) THEN scrollDistance:=-scrollDistance END; oldSetting:=TB.GetCtlValue(control); max:=TB.GetCtlMax(control); scrollDistance:=oldSetting-scrollDistance; IF scrollDistance<0 THEN scrollDistance:=0 END;IF scrollDistance>max THEN scrollDistance:=max END; TB.SetCtlValue(control, scrollDistance); scrollDistance:=oldSetting-scrollDistance; IF scrollDistance#0 THEN TE.TEPinScroll(0, scrollDistance*myDoc.data.p.lineHeight, myDoc.data) END; END END VertAction; (* Process the clicking into a text window *) PROCEDURE DoContentClick(window: TB.WindowPtr; event: TB.EventRecord); VAR control: TB.ControlHandle; value, part: INTEGER; myDoc: DocPtr; teRect: IM.Rect; BEGIN IM.SetPort(window); IM.GlobalToLocal(event.where); GetTERect(window, teRect); myDoc:=SYSTEM.VAL(DocPtr, window.refCon); IF ~IM.PtInRect(event.where, teRect) THEN (* Click into scrollbar? *) part:=TB.FindControl(event.where, window, control); CASE part OF | 0: | TB.inThumb: value:=TB.GetCtlValue(control); part:=TB.TrackControl(control, event.where, NIL); IF part#0 THEN value:=value - TB.GetCtlValue(control); IF value#0 THEN TE.TEPinScroll(0, value*myDoc.data.p.lineHeight, myDoc.data) END END ELSE part:=TB.TrackControl(control, event.where, VertAction) END ELSE TE.TEClick(event.where, FALSE, myDoc.data) END (* Click into window *) END DoContentClick; (* Process the selecton of a menu item *) PROCEDURE MenuCommand(menuResult: LONGINT); (* Item has been Chosen by MenuSelect or MenuKey *) VAR menu, item: INTEGER; Name: ME.Str255; daRefNum: INTEGER; itemHit: INTEGER; window: TB.WindowPtr; myDoc:DocPtr; fontID, fsize: INTEGER; fInfo: TE.FontInfo; oldPort: IM.GrafPtr; BEGIN menu:=SHORT(menuResult DIV 10000H); item:=SHORT(menuResult MOD 10000H); (* Get menu and item number *) window:=TB.FrontWindow(); IF window#NIL THEN myDoc:=SYSTEM.VAL(DocPtr, window.refCon) END; CASE menu OF | mApple: IF item=iAbout THEN itemHit:=TB.Alert(aAbout, NIL) ELSE TB.GetItem(TB.GetMHandle(mApple), item, Name); daRefNum:=TB.OpenDeskAcc(Name) END | mFile: CASE item OF | iNew: window:=NewWindow();AdjustScrollBars(window, TRUE);TB.ShowWindow(window) | iOpen: OpenFile; | iClose: CloseWindow; | iPageSetUp: DoPageSetUp; | iPrint: DoPrint; | iSave: SaveWindow; | iQuit: MP.ExitToShell ELSE END | mEdit: IF window#NIL THEN CASE item OF (* We don't exchange our data with the clipboard *) | iCut: TE.TECut(myDoc.data); | iCopy: TE.TECopy(myDoc.data); | iPaste: TE.TEPaste(myDoc.data); | iClear: TE.TEDelete(myDoc.data); | iSelectAll: TE.TESetSelect(0, 32767, myDoc.data) ELSE END; AdjustScrollBars(window, FALSE) END | mFont: IF window#NIL THEN TB.GetItem(TB.GetMHandle(mFont), item, Name); TE.GetFNum(Name, fontID); IM.GetPort(oldPort); IM.SetPort(myDoc.data.p.inPort); TE.TextFont(fontID); myDoc.data.p.txFont:=fontID; AdjustScrollBars(window, TRUE); AdjustTE(window); TB.InvalRect(window.portRect); IM.SetPort(oldPort) END | mSize: IF window#NIL THEN CASE item OF | 1: fsize:=9; | 2: fsize:=10; | 3: fsize:=12; | 4: fsize:=18; | 5: fsize:=24 ELSE END; IM.GetPort(oldPort); IM.SetPort(myDoc.data.p.inPort); TE.TextSize(fsize); myDoc.data.p.txSize:=fsize; TE.GetFontInfo(fInfo); myDoc.data.p.lineHeight:=fInfo.ascent+fInfo.descent+fInfo.leading; myDoc.data.p.fontAscent:=fInfo.ascent; AdjustScrollBars(window, TRUE); AdjustTE(window); TB.InvalRect(window.portRect); IM.SetPort(oldPort) END ELSE END; TB.HiliteMenu(0) END MenuCommand; (* Help routine for update *) PROCEDURE GetLocalUpdateRgn(window: TB.WindowPtr; localRgn: IM.RgnHandle); BEGIN IM.CopyRgn(window.updateRgn, localRgn); IM.OffsetRgn(localRgn, window.portBits.bounds.left, window.portBits.bounds.top) END GetLocalUpdateRgn; (* Handle activating or deactivating of a text window *) PROCEDURE DoActivate(window: TB.WindowPtr; active: BOOLEAN); VAR myDoc: DocPtr; growRect: IM.Rect; BEGIN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); IF active THEN TE.TEActivate(myDoc.data); myDoc.vScrollBar.p.contrlVis:=-1; TB.InvalRect(myDoc.vScrollBar.p.contrlRect); growRect:=window.portRect; growRect.left:=growRect.right-15; growRect.top:=growRect.bottom-15; TB.InvalRect(growRect); ELSE TE.TEDeactivate(myDoc.data); TB.HideControl(myDoc.vScrollBar); TB.DrawGrowIcon(window) END END DoActivate; (* Main loop of our program - handles all incoming events *) PROCEDURE Loop(); VAR gotEvent: BOOLEAN; event: TB.EventRecord; window: TB.WindowPtr; key: INTEGER; newsize: LONGINT; myDoc: DocPtr; growRect, oldViewRect: IM.Rect; locUpdateRgn: IM.RgnHandle; theResult: BOOLEAN; BEGIN LOOP gotEvent:=TB.WaitNextEvent(TB.everyEvent, event, 0, NIL); CASE event.what OF | TB.mouseDown: CASE TB.FindWindow(event.where, window) OF | TB.inMenuBar: MenuCommand(TB.MenuSelect(event.where)) | TB.inSysWindow: TB.SystemClick(event, window) | TB.inContent: IF window # TB.FrontWindow() THEN TB.SelectWindow(window) ELSE DoContentClick(window, event) END | TB.inDrag: TB.DragWindow(window, event.where, IM.QuickDraw.screenBits.bounds) | TB.inGoAway: IF TB.TrackGoAway(window, event.where) THEN TB.CloseWindow(window) END | TB.inGrow: IM.SetPort(window); IM.SetRect(growRect, 64, 64, 2000, 2000); newsize:=TB.GrowWindow(window, event.where, growRect); IF newsize#0 THEN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); oldViewRect:=myDoc.data.p.viewRect; locUpdateRgn:=IM.NewRgn(); GetLocalUpdateRgn(window, locUpdateRgn); TB.SizeWindow(window, SHORT(newsize MOD 10000H), SHORT(newsize DIV 10000H), TRUE); AdjustScrollBars(window, TRUE); AdjustTE(window); TB.InvalRect(window.portRect); theResult:=IM.SectRect(oldViewRect, myDoc.data.p.viewRect, oldViewRect); TB.ValidRect(oldViewRect); TB.InvalRgn(locUpdateRgn); IM.DisposeRgn(locUpdateRgn); END; | TB.inDesk, TB.inZoomIn, TB.inZoomOut: END; | TB.keyDown, TB.autoKey: (* check if cmdkey is pressed *) key:=SHORT(event.message MOD 100H); IF 8 IN SYSTEM.VAL(SET, LONG(event.modifiers)) THEN MenuCommand(TB.MenuKey(key)) ELSE window:=TB.FrontWindow(); myDoc:=SYSTEM.VAL(DocPtr, window.refCon); TE.TEKey(key, myDoc.data); (* Enter key in text *) AdjustScrollBars(window, FALSE) END | TB.updateEvt: window:=SYSTEM.VAL(TB.WindowPtr, event.message); IF window#NIL THEN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); TB.BeginUpdate(window); IM.SetPort(window); IM.EraseRect(window.portRect); TB.DrawControls(window); TB.DrawGrowIcon(window); TE.TEUpdate(window.portRect, myDoc.data); TB.EndUpdate(window) END; | TB.activateEvt: (* modifiers: bit0: 0=deactivate 1=activate *) window:=SYSTEM.VAL(TB.WindowPtr, event.message); IF window#NIL THEN DoActivate(window, ODD(event.modifiers)) END; | TB.osEvt: window:=TB.FrontWindow(); IF window#NIL THEN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); IF SYSTEM.LSH(event.message, -24) (*MOD 100H*)=TB.suspendResumeMessage THEN IF ODD(event.message) THEN (* Activate *) IM.SetPort(window); TE.TEActivate(myDoc.data); IM.InitCursor ELSE (* Deactivate *) TE.TEDeactivate(myDoc.data); IM.InitCursor END END ELSE IM.InitCursor END | TB.nullEvent: window:=TB.FrontWindow(); IF window#NIL THEN myDoc:=SYSTEM.VAL(DocPtr, window.refCon); TE.TEIdle(myDoc.data) END ELSE (* Ignore Other Event Types *) END END END Loop; (* Initalize all menus, variables etc *) PROCEDURE InitMac; VAR systemversion: LONGINT; BEGIN ME.MaxApplZone; ME.MoreMasters; IM.InitGraf(IM.QuickDraw.thePort); (* The QuickDraw Globals are proper Oberon Variables *) TE.InitFonts; TB.InitWindows; TB.InitMenus; TE.TEInit; TB.InitDialogs(NIL); IM.InitCursor; SYSTEM.PUTREG(0, 0FFFF0000H); (* everyEvent *) TB.FlushEvents; SYSTEM.PUTREG(0, 73797376H); (* gestaltSystemVersion: sysv, check for system 7 *) MO.Gestalt; SYSTEM.GETREG(8, systemversion); IF systemversion < 0700H THEN MT.SysBeep(1); MP.ExitToShell END; TB.SetMenuBar(TB.GetNewMBar(128)); (* Set up menus *) TB.AddResMenu(TB.GetMHandle(mApple), 44525652H); TB.AddResMenu(TB.GetMHandle(mFont), 464F4E54H); TB.DrawMenuBar; SYSTEM.PUTREG(0, 120); (* Set up print structure *) ME.NewHandle; SYSTEM.GETREG(8, gPrint); IM.PrOpen; IM.PrintDefault(gPrint); IM.PrClose END InitMac; BEGIN InitMac; Loop() END SampleApp.